package com.jinzecloud.reportapproval.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.deepoove.poi.config.Configure;
import com.jinzecloud.reportapproval.bean.Admin;
import com.jinzecloud.reportapproval.bean.AuthenticationTask;
import com.jinzecloud.reportapproval.bean.HandoverChecklist;
import com.jinzecloud.reportapproval.dto.AdminDto;
import com.jinzecloud.reportapproval.dto.AuditParam;
import com.jinzecloud.reportapproval.dto.DataStagingParam;
import com.jinzecloud.reportapproval.enums.AuditRoleEnums;
import com.jinzecloud.reportapproval.enums.StateEnum;
import com.jinzecloud.reportapproval.enums.TableEnums;
import com.jinzecloud.reportapproval.mapper.AdminMapper;
import com.jinzecloud.reportapproval.mapper.AuthenticationTaskMapper;
import com.jinzecloud.reportapproval.utils.*;
import com.jinzecloud.reportapproval.vo.AuthenticationTaskVo;
import com.jinzecloud.reportapproval.vo.InspResuProVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jinzecloud.reportapproval.mapper.InspResuProMapper;
import com.jinzecloud.reportapproval.bean.InspResuPro;
import com.jinzecloud.reportapproval.service.InspResuProService;

import javax.servlet.http.HttpServletRequest;


@Service("inspResuProService")
public class InspResuProServiceImpl extends ServiceImpl<InspResuProMapper, InspResuPro> implements InspResuProService {

    @Autowired
    private AuthenticationTaskMapper authenticationTaskMapper;
    @Autowired
    private FileUploadUtil fileUploadUtil;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private AdminMapper adminMapper;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<InspResuPro> inspResuProQueryWrapper = new QueryWrapper<>();
        String key = (String) params.get("key");
        inspResuProQueryWrapper.like(StrUtil.isNotBlank(key), "product_number", key)
                .or().like(StrUtil.isNotBlank(key), "product_name", key)
                .or().like(StrUtil.isNotBlank(key), "product_model", key);
        IPage<InspResuPro> page = this.page(
                new Query<InspResuPro>().getPage(params),
                inspResuProQueryWrapper
        );
        PageUtils pageUtils = new PageUtils(page);
        List<InspResuProVo> collect = page.getRecords().stream().map(inspResuPro -> {
            InspResuProVo inspResuProVo = new InspResuProVo();
            BeanUtils.copyProperties(inspResuPro, inspResuProVo);
            if (inspResuPro.getInspectionType() == 1) inspResuProVo.setInspectionType("推广鉴定");
            if (inspResuPro.getInspectionType() == 2) inspResuProVo.setInspectionType("国家支持的推广鉴定");
            if (inspResuPro.getInspectionType() == 3) inspResuProVo.setInspectionType("注册确认");
            if (inspResuPro.getInspectionType() == 4) inspResuProVo.setInspectionType("专项鉴定");
            if (inspResuPro.getInspectionType() == 5) inspResuProVo.setInspectionType("日常监督");
            if (inspResuPro.getInspectionType() == 6) inspResuProVo.setInspectionType("专项监督");
            if (inspResuPro.getInspectionType() == 7) inspResuProVo.setInspectionType("委托检测");
            return inspResuProVo;
        }).collect(Collectors.toList());
        pageUtils.setList(collect);
        return pageUtils;
    }

    @Override
    public Object auditList(DataStagingParam param) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LambdaQueryWrapper<InspResuPro> queryWrapper = new LambdaQueryWrapper<>();
        List<AdminDto> adminDto = AuditUtil.getAdminDto(authentication.getName());
        Set<Integer> roleSet = adminDto.stream().map(a -> StateEnum.getStateEnumByAuditRole(a.getRoleCode()).getState()).collect(Collectors.toSet());
        roleSet.remove(StateEnum.UN_SUBMIT.getState());
        queryWrapper.in(InspResuPro::getStatus, roleSet);
        return page(new Page<>(param.getPageNo(), param.getPageSize()), queryWrapper);
    }

    @Override
    public R audit(AuditParam auditParam) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        List<AdminDto> adminDos = AuditUtil.getAdminDto(authentication.getName());
        if (CollectionUtil.isEmpty(adminDos)) return R.error("您没有审核权限！");
        InspResuPro inspResuPro = this.getById(auditParam.getId());
        int state = inspResuPro.getStatus();
        if (!auditParam.isState()) {
            updateById(inspResuPro.setStatus(StateEnum.APPROVAL_NOT_PASS.getState())
                    .setAuditOpinion(auditParam.getAuditOpinion())
                    .setAuditDate(DateUtil.date().toDateStr()));
            return R.ok();
        }
        StateEnum currentAuditState = AuditUtil.getStateText(TableEnums.SAFETY_ASSESSMENT.getTableName(), state);
        Integer nextAuditStateIndex = AuditUtil.getNextAuditState(TableEnums.SAFETY_ASSESSMENT.getTableName(), state, adminDos.stream().map(AdminDto::getRoleCode).toList());
        AdminDto adminDto = adminDos.stream().filter(a -> StrUtil.equals(a.getRoleCode(), currentAuditState.getAuditRole()))
                .findFirst().orElse(null);
        if (adminDto == null || nextAuditStateIndex == null) return R.error("您没有审核权限！");
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER_PERSON.getCode())) inspResuPro.setUndeDept(adminDto.getAdSignature());inspResuPro.setResponsibleTime(new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date()));
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.RECORDER.getCode())) inspResuPro.setProjectUndertaker(adminDto.getAdSignature());inspResuPro.setProjectUndertakerTime(new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date()));
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) inspResuPro.setIdentificationDivision(adminDto.getAdSignature());inspResuPro.setIdentificationDivisionTime(new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date()));
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) inspResuPro.setProjectLeader(adminDto.getAdSignature());inspResuPro.setResponsibleTime(new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date()));
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) inspResuPro.setAuditor(adminDto.getAdSignature());inspResuPro.setAuditorTime(new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date()));
        if (StrUtil.equals(adminDto.getRoleCode(), AuditRoleEnums.CHECKER.getCode())) inspResuPro.setApprover(adminDto.getAdSignature());inspResuPro.setApproverTime(new SimpleDateFormat("yyyy-MM-dd HH:ss:mm").format(new Date()));
        inspResuPro.setStatus(nextAuditStateIndex)
                .setAuditOpinion(auditParam.getAuditOpinion())
                .setAuditDate(DateUtil.date().toDateStr());
        updateById(inspResuPro);
        return R.ok();
    }

    @Override
    public String export(Integer id) {
        InspResuPro inspResuPro = getById(id);
        if (inspResuPro != null) {
            QueryWrapper<Admin> adminQueryWrapper = new QueryWrapper<>();
            adminQueryWrapper.eq("ad_id", inspResuPro.getUserId());
            Admin admin = adminMapper.selectOne(adminQueryWrapper);
            inspResuPro.setInspector(admin.getAdName());
        }
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(inspResuPro));
        File tempFile = WordUtil.getWordFile("template/inspection.docx", data, Configure.builder().useSpringEL());
        String fileName = "检验结果报告审批流程";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + inspResuPro.getProductName() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + inspResuPro.getProductName() +fileName;
        FileUtil.copy(tempFile, new File(filePath + ".docx"),true);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));
        this.update(new LambdaUpdateWrapper<InspResuPro>().set(InspResuPro::getWordPath, savePath + ".docx").set(InspResuPro::getPdfPath, savePath + ".pdf").eq(InspResuPro::getId, id));
        return RequestUtils.getBasePath(request) + "upload/temp/" + inspResuPro.getProductName() + fileName + ".pdf";
    }

    public String exportWord(Integer id) {
        InspResuPro inspResuPro = getById(id);
        if (inspResuPro != null) {
            QueryWrapper<Admin> adminQueryWrapper = new QueryWrapper<>();
            adminQueryWrapper.eq("ad_id", inspResuPro.getUserId());
            Admin admin = adminMapper.selectOne(adminQueryWrapper);
            inspResuPro.setInspector(admin.getAdName());
        }
        JSONObject data = JSONObject.parseObject(JSONObject.toJSONString(inspResuPro));
        File tempFile = WordUtil.getWordFile("template/inspection.docx", data, Configure.builder().useSpringEL());
        String fileName = "检验结果报告审批流程";
        String uploadDirectory = fileUploadUtil.getUploadFilePath("temp");
        String filePath = uploadDirectory + inspResuPro.getProductName() + fileName;
        String savePath = RequestUtils.getBasePath(request) + "upload/temp/" + inspResuPro.getProductName() +fileName;
        FileUtil.copy(tempFile, new File(filePath + ".docx"),true);
        PDFUtil.WordToPdf(tempFile, new File(filePath + ".pdf"));
        this.update(new LambdaUpdateWrapper<InspResuPro>().set(InspResuPro::getWordPath, savePath + ".docx").set(InspResuPro::getPdfPath, savePath + ".pdf").eq(InspResuPro::getId, id));
        return RequestUtils.getBasePath(request) + "upload/temp/" + inspResuPro.getProductName() + fileName + ".docx";
    }


    @Override
    public String viewPdf(Integer id) {
        InspResuPro inspResuPro = getById(id);
//        String dataTime = handoverChecklist.get();
//        try {
//            keyInstrument.setDataTime(sdf.format(inputFormat.parse(dataTime)));
//        } catch (ParseException e) {
//            throw new RuntimeException(e);
//        }
        List<InspResuPro> inspResuPros = this.list(new QueryWrapper<InspResuPro>().eq("id", id).orderByAsc("id"));
//        HandoverChecklist.setDetailList(keyInstrumentDetailList);
        String s = export(id);
        return s;
    }

    @Override
    public R saveInspResuPro(InspResuPro inspResuPro) {
        QueryWrapper<InspResuPro> inspResuProQueryWrapper = new QueryWrapper<>();
        inspResuProQueryWrapper.eq("product_number", inspResuPro.getProductNumber());
        if (list(inspResuProQueryWrapper).size() >= 1) {
            return R.error("产品编号已存在");
        }else{
            save(inspResuPro);
            return R.ok();
        }
    }

    @Override
    public String viewWord(Integer id) {
        InspResuPro inspResuPro = getById(id);
//        String dataTime = handoverChecklist.get();
//        try {
//            keyInstrument.setDataTime(sdf.format(inputFormat.parse(dataTime)));
//        } catch (ParseException e) {
//            throw new RuntimeException(e);
//        }
        List<InspResuPro> inspResuPros = this.list(new QueryWrapper<InspResuPro>().eq("id", id).orderByAsc("id"));
//        HandoverChecklist.setDetailList(keyInstrumentDetailList);
        String s = exportWord(id);
        return s;
    }
}